class: inverse,left, middle background-image: url(data:image/png;base64,#background.png) background-size: cover <img src="data:image/png;base64,#LOGO_DIPLOMADO.png" width="500px"/> ##Módulo 3: Análisis masivo de datos satelitales y Google Earth Engine [GEE] ###Google Earth Engine: Aplicaciones en GEE [Parte I] José A. Lastra<br> <a href="http://github.com/JoseLastra"> Github: JoseLastra</a><br> <a href="mailto:jose.lastra@pucv.cl"> jose.lastra@pucv.cl</a> | <a href="mailto:jose.lastramunoz@wur.nl"> jose.lastramunoz@wur.nl</a><br> .large[<b><a href="https://www.pucv.cl/uuaa/site/edic/base/port/labgrs.html">LabGRS</a> | Diciembre, 2025</b>] <br> --- class: center,middle background-image: url(data:image/png;base64,#labgrs_logo.png) background-size: 35% --- ## Contenidos .pull-left[ - Trabajo con colecciones: <details> * Importación * Filtros temporales y espaciales * Creación de una imagen * Exportación de datos </details> - Funciones en GEE * Uso de **map()** - Reducciones * Temporales * Espaciales - Extracción series de tiempo <details> * Aproximación directa * Via reduce() * Series de tiempo extensas </details> ] .pull-right[ <img src="data:image/png;base64,#GEE.gif" width="450px"/> ] --- ## Colecciones -- - Dentro de GEE disponemos de una gran cantidad de información, que está agrupada en colecciones. - Cada colección corresponde a un producto diferente, ya sea satelital, modelo climático, etc. - Para llamar colecciones, vamos a considerar una estructura mínima similar a lo siguiente: ``` js var imageCollection = ee.ImageCollection('NOMBRE/PRODUCTO') ``` <script> var imageCollection = ee.ImageCollection('NOMBRE/PRODUCTO') </script> <center><img src="data:image/png;base64,#datasets.png" width="650px"/></center> --- ## Carga de colección Landsat 8 -- - Carguemos la colección 2 de Landsat 8 en nivel 1 ``` js //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") ``` <script> //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") </script> -- - La colección completa considera la información disponible para todo el catálogo (abril 2013) hasta la actualidad. -- - La declaracion `var xx = ee.Something` es simil a la creación o asignación de un objeto en R vía `obj <- some()`. -- - Si imprimimos los resultados en consola usando `print(imageCollection,'colección landsat')` obtendremos el siguiente error: <center><img src="data:image/png;base64,#img1.png" width="450px"/></center> --- ## Filtros sobre una colección -- - Para poder visualizar solo la información que nos interesa o filtrar en base a criterios específicos (región de interés, fechas, cobertura nubosa, etc.) -- - GEE dispone de varias formas que podemos emplear como: **filter()**, **filterBounds()**, **filterDate()**, etc. - Filtrar la información, nos permitirá poder imprimir en la consola los resultados e inspeccionarlos de forma más simple y directa. -- - Utilice una geometría básica, dibujada en el mapa y aplique la función `filterBounds(nombre_geometria)`. ``` js //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry); print(imageCollection,'colección landsat'); ``` <script> //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry); print(imageCollection,'colección landsat'); </script> --- -- - Para este filtro el resultado debe tener un total de 447 elementos (a la fecha de creación de esta clase). -- - Esto variará según la zona escogida por cada uno y la fecha de consulta. <center><img src="data:image/png;base64,#img2.png" width="400px"/></center> - Ahora, apliquemos un filtro de fechas considerando el año 2021 (ene - dic). ``` js var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31'); print(imageCollection,'colección landsat'); ``` <script> var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31'); print(imageCollection,'colección landsat'); </script> <center><img src="data:image/png;base64,#img3.png" width="400px"/></center> --- -- - También podemos aplicar otros tipos de filtros como generales empleando `filter()`, `ee.Filter()` y los metadatos o propiedades de las imágenes ``` js var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // filtro por nubosidad en tierra .filter(ee.Filter.lt('CLOUD_COVER_LAND',50)); ``` <script> var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // filtro por nubosidad en tierra .filter(ee.Filter.lt('CLOUD_COVER_LAND',50)); </script> <center><img src="data:image/png;base64,#img4.png" width="450px"/></center> --- ``` js var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // Filtro por path y row .filter(ee.Filter.or( ee.Filter.and(ee.Filter.eq('WRS_PATH', 233), ee.Filter.eq('WRS_ROW', 83)))); ``` <script> var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // Filtro por path y row .filter(ee.Filter.or( ee.Filter.and(ee.Filter.eq('WRS_PATH', 233), ee.Filter.eq('WRS_ROW', 83)))); </script> <center><img src="data:image/png;base64,#img4a.png" width="450px"/></center> -- - Nosotros solo filtraremos por nubosidad en tierra (**CLOUD_COVER_LAND < 50%**) y ordenaremos las imágenes de menor a mayor __CCL__ usando la función **sort()** --- ``` js //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // filtro por nubosidad en tierra .filter(ee.Filter.lt('CLOUD_COVER_LAND',50)) // Ordenar por cobertura nubosa, ascendente. .sort('CLOUD_COVER_LAND'); ``` <script> //Carga colección Landsat 8 (en bruto) var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1") //filtro por geometría .filterBounds(geometry) //filtro de fecha .filterDate('2021-01-01', '2021-12-31') // filtro por nubosidad en tierra .filter(ee.Filter.lt('CLOUD_COVER_LAND',50)) // Ordenar por cobertura nubosa, ascendente. .sort('CLOUD_COVER_LAND'); </script> <center><img src="data:image/png;base64,#img5.png" width="450px"/></center> -- - La fecha de la imagen menos nubosa con estos filtros es: **2021-04-09** --- ## Creación de imagen -- - Cada colección dispone de diferentes archivos dentro de ella, desde rasters individuales hasta archivos multibanda. - Podemos crear una imagen empleando uno de los archivos dentro de la colección o podemos crear reducciones de toda la colección (cosa que veremos más adelante). - **Importante:** Debemos tener en cuenta como se almacena la información y los nombres de las capas de información para seleccionar. - La estructura base es la siguiente: ``` js var image = ee.Image('LANDSAT/LC08/C02/T1/LC08_001083_20210409') ``` <script> var image = ee.Image('LANDSAT/LC08/C02/T1/LC08_001083_20210409') </script> -- - Debemos considerar la información del id de la imagen incluyendo toda la ruta al dataset. --- ## Creación de imagen -- - También, podemos usar una colección de imágenes filtrada como la generada anteriormente y seleccionar los datos internamente - Esto nos permite aplicar filtros adicionales y seleccionar solo cierta información. ``` js //Imagen menos nubosa para el periodo var image = ee.Image((imageCollection) //Selección de bandas ópticas .select(['B[1-7]']) //selección de imagen menos nubosa .first()); print(image, 'L8 menos nubosa'); ``` <script> //Imagen menos nubosa para el periodo var image = ee.Image((imageCollection) //Selección de bandas ópticas .select(['B[1-7]']) //selección de imagen menos nubosa .first()); print(image, 'L8 menos nubosa'); </script> <center><img src="data:image/png;base64,#img6.png" width="450px"/></center> --- ## Visualizando datos -- - La función que nos permite agregar información al mapa es **Map.addLayer()** - Donde podemos agregar una colección de imágenes, una imagen, vectores, etc. ``` js //Agregando imagen a la visualización Map.addLayer(image,{}, 'L8 Image sin parámetros de visualización'); //Mejorando la visualización Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], min: 2000, max: 9000, gamma: 0.25}, 'Mejor L8'); ``` <script> //Agregando imagen a la visualización Map.addLayer(image,{}, 'L8 Image sin parámetros de visualización'); //Mejorando la visualización Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], min: 2000, max: 9000, gamma: 0.25}, 'Mejor L8'); </script> --- class: center,middle background-image: url(data:image/png;base64,#comparison.png) background-size: 80% --- ## Exportación de datos ráster -- - Al procesar la información dentro de GEE, podemos optimizar el uso de espacio y descargar solo los resultados o solo la imagen acotada a una zona de nuestro interés. - Para exportar podemos hacerlo a un asset (dentro de GEE), Google Cloud o Google Drive. - En el caso de Google Cloud debemos considerar pago por uso de almacenamiento. - En el caso de Google Drive y assets estamos limitados al espacio de cada plataforma. * Para los **assets** 250 GB ó 10.000 archivos * Google Drive, depende del nivel de usuario. -- - **Consideraciones al exportar**: * Los datos exportados deben tener el mismo datatype. * Las funciones de exportación esperan una imagen como entrada, <b>No una colección de imágenes</b>. * *maxPixels* permite controlar el número de pixeles a exportar, por defecto ***1e8 (100.000.000 px.)*** * Cuando se alcanza el límite de exportación, GEE divide nuestro archivo. --- ## Exportando a Google Drive -- - Dibuje una región de interés (**ROI**) dentro del área de la imagen que tenemos desplegada y úsela como región para exportar ``` js //Exportar datos // Google Drive Export (nota: requiere que el usuario oprima 'Run') Export.image.toDrive({ image: image, //imagen a descargar description: 'image_example_drive', // scale: 30,//tamaño de salida del pixel region: roi, // región de interés para exportación crs: 'EPSG:4326',// sistema de referencia del archivo 4326 equivale a LatLong WGS 84 maxPixels: 10e11 //número de pixeles para exportación 10e11 = 100,000,000,000 }); ``` <script> //Exportar datos // Google Drive Export (nota: requiere que el usuario oprima 'Run') Export.image.toDrive({ image: image, //imagen a descargar description: 'image_example_drive', // scale: 30,//tamaño de salida del pixel region: roi, // región de interés para exportación crs: 'EPSG:4326',// sistema de referencia del archivo 4326 equivale a LatLong WGS 84 maxPixels: 10e11 //número de pixeles para exportación 10e11 = 100,000,000,000 }); </script> --- ## Exportando al Asset ``` js // Asset Folder Export (nota: requiere que el usuario oprima 'Run') Export.image.toAsset({ image: image, description: 'image_example_asset', assetId: 'users/joselastra/image_example',//reemplazar con su nombre de usuario scale: 30, region: roi, pyramidingPolicy: {'.default':'mean'}, // para datos discretos {'.default':'sample' o 'mode'} maxPixels: 10e11, // 10e11 = 100,000,000,000 }); ``` <script> // Asset Folder Export (nota: requiere que el usuario oprima 'Run') Export.image.toAsset({ image: image, description: 'image_example_asset', assetId: 'users/joselastra/image_example',//reemplazar con su nombre de usuario scale: 30, region: roi, pyramidingPolicy: {'.default':'mean'}, // para datos discretos {'.default':'sample' o 'mode'} maxPixels: 10e11, // 10e11 = 100,000,000,000 }); </script> --- ## Exportación de datos ráster -- - Para todas las exportaciones, se requiere que el usuario active el **task** para ser enviado al servidor. <center><img src="data:image/png;base64,#img7.png" width="420px"/></center> -- - Si queremos cancelar uno o varios task, podemos hacerlo directamente, ir al [**Task Manager**](https://code.earthengine.google.com/tasks) o al [**Task Page**](https://console.cloud.google.com/earth-engine/) en la consola de GCloud. <center><img src="data:image/png;base64,#img8.png" width="480px"/></center> --- ## Creación y aplicación de funciones -- - **Funciones**: Dentro de la sección **Docs** de GEE, tiene a disposición funciones específicas para trabajar con imágenes y con colecciones de imágenes, dependiendo de cuál sea el análisis a realizar: funciones booleanas, matemáticas, transformaciones, análisis espectral, entre otros. -- - Para aplicar masivamente un análisis, normalmente se recurre al uso de ciclos. -- - **Importante:** En nuestro code editor se recomienda evitar a toda costa el uso convencional de ciclos; debido a que esto trae la operación al explorador y puede generar errores de funcionamiento. --- ## Uso de map() -- - En GEE se dispone de la función **map()** para lograr el procesamiento masivo de datos (colecciones de imágenes, geometrías, etc.) -- - La función **map()** envía automáticamente la operación a los servidores de Google para ser paralelizado permitiendo tener resultados en segundos. -- - Usaremos el producto Sentinel 2 (MSI) de nivel 2 y filtraremos una zona de interés considerando todas las imágenes disponibles. -- - **Importante:** recuerde que puede agregar más filtros: nubosidad, calidad de la imagen, etc. --- ## Uso de map() y funciones propias -- - Carga de datos y filtro de la colección ``` js /* Funciones propias aplicadas a colecciones de datos satelitales*/ //Carga colección Sentinel 2 (SR) var s2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED") .filterBounds(geometry) .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',50)); print(s2,'colección Sentinel'); ``` <script> /* Funciones propias aplicadas a colecciones de datos satelitales*/ //Carga colección Sentinel 2 (SR) var s2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED") .filterBounds(geometry) .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',50)); print(s2,'colección Sentinel'); </script> <center><img src="data:image/png;base64,#img9.png" width="500px"/></center> --- ## Uso de map() y funciones propias -- - Utilizaremos de forma complementaria las bandas: **SCL** y **MSK_CLDPRB**. ``` js /* * función para limpieza de nubes * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 enmascarada */ var maskCloudSR = function(image) { var cloudProb = image.select('MSK_CLDPRB'); // selección prob nubes var cloud = cloudProb.lt(50); // 50% var scl = image.select('SCL');// selección mapa de clasificación var shadow = scl.eq(3); // 3 = cloud shadow var cirrus = scl.eq(10); // 10 = cirrus // Probabilidad menor al 50% o sombre de nube y cirrus var mask = cloud.and(cirrus.neq(1)).and(shadow.neq(1)); return image.addBands(image.updateMask(mask).divide(10000), null, true); } // Aplicación con map var s2_clean = s2.map(maskCloudSR); ``` <script> /* * función para limpieza de nubes * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 enmascarada */ var maskCloudSR = function(image) { var cloudProb = image.select('MSK_CLDPRB'); // selección prob nubes var cloud = cloudProb.lt(50); // 50% var scl = image.select('SCL');// selección mapa de clasificación var shadow = scl.eq(3); // 3 = cloud shadow var cirrus = scl.eq(10); // 10 = cirrus // Probabilidad menor al 50% o sombre de nube y cirrus var mask = cloud.and(cirrus.neq(1)).and(shadow.neq(1)); return image.addBands(image.updateMask(mask).divide(10000), null, true); } // Aplicación con map var s2_clean = s2.map(maskCloudSR); </script> --- ## Aplicando varias funciones - Dentro de nuestro código, podemos emplear una sola función que ejecute todos los análisis y procesamientos que requerimos y aplicarlos de una sola vez. - Desventaja: si algo falla en el código es más difícil de encontrar. - Por esta razón, lo recomendable es modularizar los procesos y ponerlos en funciones diferentes. - A continuación, crearemos una función para cortar la imagen a un área de interés. Empleando un ROI creado a partir de las herramientas de geometría. - Crear función de corte ``` js /* * función para cortar imágenes al área de estudio * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 cortada */ var crop = function (image){ var crop1 = image.clip(roi); return image.addBands(crop1, null, true); }; ``` <script> /* * función para cortar imágenes al área de estudio * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 cortada */ var crop = function (image){ var crop1 = image.clip(roi); return image.addBands(crop1, null, true); }; </script> --- ## Aplicando varias funciones .pull-left[ <center><img src="data:image/png;base64,#img11.png" width="400px"/></center> ] .pull-right[ ``` js var s2_clean = s2.map(maskCloudSR).map(crop); ``` <script> var s2_clean = s2.map(maskCloudSR).map(crop); </script> <center><img src="data:image/png;base64,#img12.png" width="300px"/></center> ] --- ## Agregando información a nuestra colección -- - Además de la información que viene por defecto en el producto, el usuario puede crear nueva información a partir de una función de cálculo (ej. NDVI, EVI, temperatura, etc.) y agregarla a dentro de la colección. -- - Realizaremos el cálculo del Índice de vegetación de diferencia normalizada (NDVI), empleando la información de nuestra colección de nombre **s2_clean**. -- - **Importante:** podemos generar una función empleando operadores matemáticos directos o a partir de funciones disponibles dentro de GEE. El resultado es el mismo. ``` js /* * Cálculo NDVI * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 original + NDVI */ // Versión simple var NDVI = function(img){ var index = img.normalizedDifference(['B8','B4']).rename('NDVI'); return img.addBands(index, null, true); }; // Versión con operadores matemáticos var NDVI2 = function(img){ var index = img.select('B8').subtract(img.select('B4')) .divide(img.select('B8').add(img.select('B4'))) return img.addBands(index, null, true); }; ``` <script> /* * Cálculo NDVI * @param {ee.Image} imagen Sentinel-2 * @return {ee.Image} imagen Sentinel-2 original + NDVI */ // Versión simple var NDVI = function(img){ var index = img.normalizedDifference(['B8','B4']).rename('NDVI'); return img.addBands(index, null, true); }; // Versión con operadores matemáticos var NDVI2 = function(img){ var index = img.select('B8').subtract(img.select('B4')) .divide(img.select('B8').add(img.select('B4'))) return img.addBands(index, null, true); }; </script> -- - Haremos uso de la versión 1 --- ## Cálculo NDVI ``` js // aplicación NDVI var s2_NDVI = s2_clean.map(NDVI); print(s2_NDVI, 'NDVI sentinel data'); // Visualización var NDVI_params = {min:-0.1, max:1, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ], bands: 'NDVI'}; Map.addLayer(s2_NDVI.first(), NDVI_params, 'NDVI'); ``` <script> // aplicación NDVI var s2_NDVI = s2_clean.map(NDVI); print(s2_NDVI, 'NDVI sentinel data'); // Visualización var NDVI_params = {min:-0.1, max:1, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ], bands: 'NDVI'}; Map.addLayer(s2_NDVI.first(), NDVI_params, 'NDVI'); </script> --- class: middle <center><img src="data:image/png;base64,#img13.png" width="650px"/></center> <center><img src="data:image/png;base64,#img14.png" width="550px"/></center> --- ## Reducciones o agregaciones temporales - Las reducciones (**reducers**) se utilizan para generar informacion nueva a nivel **temporal y/o espacial**. - Estas agregaciones pueden ser de diferentes estadísticas y tipos, disponiendo de elementos como suma o conteo. <center><img src="data:image/png;base64,#https://developers.google.com/static/earth-engine/images/Reduce_ImageCollection.png" width="220px"/></center> .center[Fuente: [Google Developers, 2021](https://developers.google.com/earth-engine/guides/reducers_image_collection)] --- ## Reducciones o agregaciones temporales -- - Empleando nuestro set de datos de nombre **s2_NDVI** realicemos una reducción considerando solo el verano de 2021-22 (Dic-Ene-Feb) ``` js // Creando reducción var s2_ver = s2_NDVI //colección .filterDate('2021-12-01', '2022-02-28') // selección de verano .select(['B.*', 'NDVI']) //selección de datos a reducir .reduce(ee.Reducer.mean()); // reductor ``` <script> // Creando reducción var s2_ver = s2_NDVI //colección .filterDate('2021-12-01', '2022-02-28') // selección de verano .select(['B.*', 'NDVI']) //selección de datos a reducir .reduce(ee.Reducer.mean()); // reductor </script> <center><img src="data:image/png;base64,#img15.png" width="420px"/></center> --- -- - Visualicemos los resultados ``` js // Parámetros de visualización var NDVI_params = {min:-0.1, max:1, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ], bands: 'NDVI_mean'}; var RGB_params = { min: 0.0, max: 0.3, bands: ['B4_mean', 'B3_mean', 'B2_mean'], } // info al mapa Map.addLayer(s2_ver, NDVI_params, 'NDVI mean'); Map.addLayer(s2_ver, RGB_params, 'RGB clean', false) ``` <script> // Parámetros de visualización var NDVI_params = {min:-0.1, max:1, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ], bands: 'NDVI_mean'}; var RGB_params = { min: 0.0, max: 0.3, bands: ['B4_mean', 'B3_mean', 'B2_mean'], } // info al mapa Map.addLayer(s2_ver, NDVI_params, 'NDVI mean'); Map.addLayer(s2_ver, RGB_params, 'RGB clean', false) </script> --- class: center,middle background-image: url(data:image/png;base64,#img16.png) background-size: 80% --- ## Reducciones o agregaciones temporales -- - Además del ejemplo de reducción visto sobre la colección, también podemos obtener estadísticos zonales empleando **geometrías** o **feature collections** mediante las funciones **reduceRegion()** o **reduceRegions()**. -- - Primero dibuje un polígono dentro de una zona de interés y úselo para extraer la información de sus datos de verano. ``` js //Estadísticas de zona // valor promedio para polígono de interés var mean = s2_ver.reduceRegion({ geometry: zona, reducer: ee.Reducer.mean(), scale: 10 // resolución de archivos }); print(mean); ``` <script> //Estadísticas de zona // valor promedio para polígono de interés var mean = s2_ver.reduceRegion({ geometry: zona, reducer: ee.Reducer.mean(), scale: 10 // resolución de archivos }); print(mean); </script> --- class: middle <center><img src="data:image/png;base64,#img17.png" width="375px"/></center> --- ## Reducciones o agregaciones temporales -- - Para calcular las estadícticas de zona en áreas específicas, cargue en sus **Assets** el archivo de nombre **zonas.zip** - Luego lo importaremos a nuestro script y calcularemos el valor promedio para todos los polígonos en nuestro asset. <center><img src="data:image/png;base64,#img18.png" width="470px"/></center> --- class: middle .pull-left[ ``` js //Para varios polígonos var means = s2_ver.reduceRegions({ collection: zonas, reducer: ee.Reducer.mean(), scale: 10 // resolución de archivos }); print(means,'means values'); ``` <script> //Para varios polígonos var means = s2_ver.reduceRegions({ collection: zonas, reducer: ee.Reducer.mean(), scale: 10 // resolución de archivos }); print(means,'means values'); </script> ] .pull-right[ <center><img src="data:image/png;base64,#img19.png" width="500px"/></center> ] --- ## Exportando información tabular -- - La información extraída a los polígonos puede ser exportada al igual que las imágenes, para ser analizada posteriormente en otro programa o plataforma. .pull-left[ ``` js //descarga de datos tabulares sin geometría // Selección de columnas var salida = means.select(['N.*','B.*'], null, false); // Table to Drive Export Example Export.table.toDrive({ collection: salida, description: 'ejemplo_descarga_csv', fileFormat: 'CSV' }); ``` <script> //descarga de datos tabulares sin geometría // Selección de columnas var salida = means.select(['N.*','B.*'], null, false); // Table to Drive Export Example Export.table.toDrive({ collection: salida, description: 'ejemplo_descarga_csv', fileFormat: 'CSV' }); </script> ] .pull-right[ ``` js //descarga de datos tabulares con geometría // Table to Drive Export Example Export.table.toDrive({ collection: means, description: 'ejemplo_descarga_shp', fileFormat: 'SHP' }); ``` <script> //descarga de datos tabulares con geometría // Table to Drive Export Example Export.table.toDrive({ collection: means, description: 'ejemplo_descarga_shp', fileFormat: 'SHP' }); </script> ] --- ## Bibliografía complementaria - Earth Engine Code Editor | Google Earth Engine |. (s.f.). Google Developers. https://developers.google.com/earth-engine/guides/playground - Gorelick, N., Hancher, M., Dixon, M., Ilyushchenko, S., Thau, D., & Moore, R. (2017). Google Earth Engine: Planetary-scale geospatial analysis for everyone. Remote sensing of Environment, 202, 18-27. [Ver](https://www.sciencedirect.com/science/article/pii/S0034425717302900) - Mutanga, O., & Kumar, L. (2019). Google earth engine applications. Remote Sensing, 11(5), 591. [Ver](https://www.mdpi.com/2072-4292/11/5/591/htm) - Zhao, Q., Yu, L., Li, X., Peng, D., Zhang, Y., & Gong, P. (2021). Progress and trends in the application of Google Earth and Google Earth Engine. Remote Sensing, 13(18), 3778. [Ver](https://www.mdpi.com/2072-4292/13/18/3778) --- class: middle 